package com.randi.web.controller.system;

import com.randi.common.annotation.LogAnnotation;
import com.randi.common.core.domain.Result;
import com.randi.common.enums.BusinessType;
import com.randi.common.enums.MenuTypeEnum;
import com.randi.common.enums.ResultCode;
import com.randi.common.core.domain.entity.SysMenu;
import com.randi.system.domain.dto.sysMenu.ButtonDTO;
import com.randi.system.domain.dto.sysMenu.CatalogDTO;
import com.randi.system.domain.dto.sysMenu.MenuDTO;
import com.randi.system.domain.params.SysMenuParam;
import com.randi.system.service.ISysMenuService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.modelmapper.ModelMapper;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author ziye
 */
@RestController
@RequestMapping("system/menu")
@Api(tags = "菜单管理")
public class SysMenuController {

    @Resource
    private ISysMenuService iSysMenuService;

    /**
     * 获取列表
     *
     * @param sysMenuParam 检索参数
     * @return Result
     */
    @PostMapping("/list")
    @ApiOperation(value = "获取列表", notes = "")
    @PreAuthorize("@auth.hasPermission('system:menu:list')")
    public Result selectList(@RequestBody SysMenuParam sysMenuParam) {
        List<SysMenu> sysMenus = iSysMenuService.selectSysMenuList(sysMenuParam);
        return Result.success().put(sysMenus);
    }

    /**
     * 获取树形列表
     *
     * @param sysMenuParam sysMenuParam
     * @return Result
     */
    @PostMapping("/tree")
    @ApiOperation(value = "获取树形列表", notes = "")
    @PreAuthorize("@auth.hasPermission('system:menu:list')")
    public Result selectTreeList(@RequestBody SysMenuParam sysMenuParam) {
        List<SysMenu> sysMenus = iSysMenuService.selectSysMenuTreeList(sysMenuParam);
        return Result.success().put(sysMenus);
    }

    /**
     * 查看详情
     *
     * @param menuId menuId
     * @return Result
     */
    @GetMapping("/detail/{menuId}")
    @ApiOperation(value = "查看详情", notes = "")
    @PreAuthorize("@auth.hasPermission('system:menu:list')")
    public Result selectById(@PathVariable Long menuId) {
        SysMenu sysMenu = iSysMenuService.selectSysMenuById(menuId);
        return Result.success().put(sysMenu);
    }

    /**
     * 添加数据
     *
     * @param <T>         泛型
     * @param menuType    菜单类型
     * @param requestBody 请求体
     * @return Result
     */
    private <T> Result insertSysMenu(MenuTypeEnum menuType, @RequestBody T requestBody) {
        SysMenu sysMenu = new ModelMapper().map(requestBody, SysMenu.class);
        sysMenu.setMenuType(menuType);
        int status = iSysMenuService.insertSysMenu(sysMenu);
        if (status == 0) {
            return Result.error(ResultCode.BUSINESS_INSERT_ERROR);
        }
        return Result.success(ResultCode.BUSINESS_INPUT_SUCCESS);
    }

    /**
     * 添加目录
     *
     * @param catalogBody 目录信息
     * @return 结果
     */
    @PostMapping("/insert/catalog")
    @ApiOperation(value = "添加目录", notes = "")
    @PreAuthorize("@auth.hasPermission('system:menu:add')")
    @LogAnnotation(module = "菜单管理", value = "添加目录", businessType = BusinessType.INSERT)
    public Result insertCatalog(@Validated @RequestBody CatalogDTO catalogBody) {
        return insertSysMenu(MenuTypeEnum.CATALOG, catalogBody);
    }

    /**
     * 添加菜单
     *
     * @param menuBody 菜单信息
     * @return 结果
     */
    @PostMapping("/insert/menu")
    @ApiOperation(value = "添加菜单", notes = "")
    @PreAuthorize("@auth.hasPermission('system:menu:add')")
    @LogAnnotation(module = "菜单管理", value = "添加菜单", businessType = BusinessType.INSERT)
    public Result insertMenu(@Validated @RequestBody MenuDTO menuBody) {
        return insertSysMenu(MenuTypeEnum.MENU, menuBody);
    }

    /**
     * 添加菜单按钮
     *
     * @param buttonBody 菜单按钮信息
     * @return 结果
     */
    @PostMapping("/insert/button")
    @ApiOperation(value = "添加按钮", notes = "")
    @PreAuthorize("@auth.hasPermission('system:menu:add')")
    @LogAnnotation(module = "菜单管理", value = "添加菜单按钮", businessType = BusinessType.INSERT)
    public Result insertButton(@Validated @RequestBody ButtonDTO buttonBody) {
        return insertSysMenu(MenuTypeEnum.BUTTON, buttonBody);
    }

    /**
     * 修改菜单信息
     *
     * @param <T>         泛型
     * @param requestBody requestBody
     * @return Result
     */
    private <T> Result updateSysMenu(@RequestBody T requestBody) {
        SysMenu sysMenu = new ModelMapper().map(requestBody, SysMenu.class);
        if (sysMenu.getMenuId() == null) {
            return Result.error(ResultCode.PARAM_ERROR);
        }
        int status = iSysMenuService.updateSysMenu(sysMenu);
        if (status == 0) {
            return Result.error(ResultCode.BUSINESS_EDITOR_ERROR);
        }
        return Result.success(ResultCode.BUSINESS_EDITOR_SUCCESS);
    }

    /**
     * 修改目录
     *
     * @param catalogBody 目录信息
     * @return 结果
     */
    @PostMapping("/update/catalog")
    @ApiOperation(value = "修改目录", notes = "")
    @PreAuthorize("@auth.hasPermission('system:menu:edit')")
    @LogAnnotation(module = "菜单管理", value = "修改目录", businessType = BusinessType.UPDATE)
    public Result updateCatalog(@Validated @RequestBody CatalogDTO catalogBody) {
        return updateSysMenu(catalogBody);
    }

    /**
     * 修改菜单
     *
     * @param menuBody 菜单信息
     * @return 结果
     */
    @PostMapping("/update/menu")
    @ApiOperation(value = "修改菜单", notes = "")
    @PreAuthorize("@auth.hasPermission('system:menu:edit')")
    @LogAnnotation(module = "菜单管理", value = "修改菜单", businessType = BusinessType.UPDATE)
    public Result updateMenu(@Validated @RequestBody MenuDTO menuBody) {
        return updateSysMenu(menuBody);
    }

    /**
     * 修改菜单按钮
     *
     * @param buttonBody 菜单按钮信息
     * @return 结果
     */
    @PostMapping("/update/button")
    @ApiOperation(value = "修改菜单按钮", notes = "")
    @PreAuthorize("@auth.hasPermission('system:menu:edit')")
    @LogAnnotation(module = "菜单管理", value = "修改菜单按钮", businessType = BusinessType.UPDATE)
    public Result updateButton(@Validated @RequestBody ButtonDTO buttonBody) {
        return updateSysMenu(buttonBody);
    }


    /**
     * 删除数据
     *
     * @param menuIds menuIds
     * @return 结果
     */
    @PostMapping("/delete")
    @ApiOperation(value = "删除数据", notes = "")
    @PreAuthorize("@auth.hasPermission('system:menu:delete')")
    @LogAnnotation(module = "菜单管理", value = "删除数据", businessType = BusinessType.DELETE)
    public Result deleteBatch(@RequestBody List<Long> menuIds) {
        int status = iSysMenuService.deleteBatchSysMenu(menuIds);

        if (status == 0) {
            return Result.error(ResultCode.BUSINESS_DELETE_ERROR);
        }
        return Result.success(ResultCode.BUSINESS_DELETE_SUCCESS);
    }
}
